package apobates.gui.formatter;

import apobates.gui.formatter.packet.JsonResult;
import apobates.gui.formatter.tree.*;
import apobates.gui.formatter.util.Core;
import com.google.gson.JsonElement;
import javafx.beans.property.SimpleMapProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.util.*;

/**
 * JavaFx GUI Json Tree视图
 * @since 20230312
 */
public class JsonTreeController {
    // 左侧的Tree
    @FXML
    private TreeView treeViewer;
    // 底部的表单
    @FXML
    private TextField nodeName;
    @FXML
    private TextField nodeValue;
    // 搜索节点按钮
    @FXML
    private Button findNodeBtn;
    // 搜索节点结果
    @FXML
    private ComboBox<JsonNodeItem> searchBox;
    // 整体布局
    @FXML
    private VBox treeLayout;
    // 正文区域
    @FXML
    private HBox bodySection;
    // 底部区域
    @FXML
    private AnchorPane footSection;
    // 右侧的详细表单
    @FXML
    private GridPane nodeViewer;
    @FXML
    private TextField showNodePath;
    @FXML
    private TextField showNodeName;
    @FXML
    private TextArea showNodeTxt;
    @FXML
    private TextField showNodeType;
    @FXML
    private Button showClearBtn;
    //搜索结果
    private SimpleMapProperty<String,TreeItem<JsonNodeItem>> searchResult;
    // 搜索表单
    private SearchNodeForm searchForm;
    private JsonNodeTreeSearcher searcher;
    private static JsonNodeTreeGsonBuilder builder;
    static {
        builder = new JsonNodeTreeGsonBuilder();
    }
    @FXML
    public void initialize() throws NoSuchMethodException, JsonParseException {
        // 变化策略
        treeLayout.setVgrow(bodySection, Priority.ALWAYS);
        treeLayout.setVgrow(footSection, Priority.NEVER);
        //主控制器@3
        String jstr = JsonResult.getInstance().getResult();
        this.buildTreeView(jstr);
        // 实例化搜索表单
        searchForm = new SearchNodeForm();
        // 实例化搜索
        searcher = new JsonNodeTreeSearcher();
        // 侦听搜索结果的值
        searcher.getResultData().addListener((ListChangeListener.Change<? extends TreeItem<JsonNodeItem>> c)-> {
            // 找到一个推一个
            for (TreeItem<JsonNodeItem> node: c.getList()) {
                // 避免重复add
                if(!searchBox.getItems().contains(node.getValue())){
                    searchBox.getItems().add(node.getValue());
                    this.searchResult.get().put(node.getValue().toString(), node);
                }
            }
        });
        // 绑定输入框的值
        searchForm.nameProperty().bind(nodeName.textProperty());
        searchForm.valueProperty().bind(nodeValue.textProperty());
        // 搜索结果
        searchResult = new SimpleMapProperty<>(FXCollections.observableHashMap());
        // 选择值后选中指定行/滚动到该行
        searchBox.valueProperty().addListener((ObservableValue<? extends JsonNodeItem> observableValue, JsonNodeItem oldNode, JsonNodeItem curNode)-> {
            System.out.println("[JTC][Change]prev:"+oldNode+", curr:"+curNode);
            if(null != curNode) {
                // 显示当前节点
                TreeItem<JsonNodeItem> searchNodeItem = searchResult.get(curNode.toString());
                int activeRow = showJsonItem(searchNodeItem);
                if (activeRow != -1) {
                    // 滚动位置
                    treeViewer.scrollTo(activeRow);
                    // 选中
                    MultipleSelectionModel msm = treeViewer.getSelectionModel();
                    msm.select(searchNodeItem);
                }
            }
        });
        // 值变化时:System.out.println("[JTC]searchForm current tostring:"+newValue);
        searchForm.contact((ObservableValue<? extends String> observable, String oldValue, String newValue)-> {
            // System.out.println("[JTC]searchForm current tostring:"+newValue);
            if(!oldValue.equals(newValue) && findNodeBtn.isDisable()){
                findNodeBtn.setDisable(false);
            }
        });
    }
    // expand当前节点的父节点. 一直到Root
    // 返回：节点在展开后的row值
    private int showJsonItem(TreeItem<JsonNodeItem> nodeItem){
        // 是否展开当前的子节点?
        TreeItem<JsonNodeItem> parent = nodeItem.getParent();
        while(null!=parent && !parent.isLeaf()){
            parent.setExpanded(true);
            parent = parent.getParent();
        }
        return treeViewer.getRow(nodeItem);
    }
    // 当前stage
    private Stage getCurrentStage(){
        return (Stage) treeLayout.getScene().getWindow();
    }
    // 节点点击后触发
    private void treeItemHandler(Object newValue){
        // System.out.println("[JTC][1]treeitem listener: ");
        try {
            TreeItem<JsonNodeItem> tiIns = (TreeItem<JsonNodeItem>) newValue;
            if(null != tiIns){
                showNodeName.setText(tiIns.getValue().getName());
                showNodeTxt.setText(tiIns.getValue().getClearValue());
                showNodeType.setText(tiIns.getValue().getType().getSymbol());
                // 父节点的名称
                List<String> box = AbstractJsonNodeBuilder.getParentNames(tiIns);
                showNodePath.setText(String.join("/", box));
            }
        }catch (ClassCastException e){
            throw new RuntimeException(e);
        }
    }
    // 填充treeViewer
    public void buildTreeView(String jsonStr)throws JsonParseException{
        // System.out.println("[JTC][0]build tree view for arg");
        // ------------------------------------------------------>Gson
        JsonElement jsonValue = Core.parseJson(jsonStr);
        // 默认展开
        treeViewer.setRoot(builder.build(jsonValue));
        //
        treeViewer.getRoot().setExpanded(true);
        // 展开
        treeViewer.getRoot().addEventHandler(TreeItem.branchExpandedEvent(),new EventHandler<TreeItem.TreeModificationEvent>() {
            @Override
            public void handle(TreeItem.TreeModificationEvent event) {
                String nodeValue = event.getSource().getValue().toString();
                // System.out.println("[JTC]节点: "+nodeValue+", is expanded");
            }
        });
        // 折叠
        treeViewer.getRoot().addEventHandler(TreeItem.branchCollapsedEvent(),new EventHandler<TreeItem.TreeModificationEvent>() {
            @Override
            public void handle(TreeItem.TreeModificationEvent event) {
                String nodeValue = event.getSource().getValue().toString();
                // System.out.println("[JTC]节点: "+nodeValue+", is collapsed");
            }
        });
        // 点击某个节点内容显示在: propViewer
        treeViewer.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> treeItemHandler(newValue));
    }
    // 底部: 搜索动作
    @FXML
    protected void seekNodeAction(ActionEvent event){
        // System.out.println("[JTC][4]search action start:");
        // 清空:搜索结果 + 搜索结果下拉框
        try {
            if (null != this.searchBox.getItems() && !this.searchBox.getItems().isEmpty()) {
                this.searchBox.getItems().clear();
            }
            searchResult.get().clear();
        }catch (NullPointerException e){
            System.out.println("[JTC][4]clear search box is null");
        }
        // 显示loading
        findNodeBtn.setDisable(true);
        // 搜索指定的searchForm
        searcher.search(treeViewer.getRoot(), searchForm);
        // 若没有找到提示
        if(searchBox.getItems().isEmpty()){
            // 会遮盖掉弹窗
            getCurrentStage().setAlwaysOnTop(false);
            // 提示searchbox
            searchBox.setPromptText("未找到匹配");
            Alert a = new Alert(Alert.AlertType.WARNING, "未匹配到满足条件的节点", ButtonType.CLOSE);
            // show the dialog
            a.showAndWait();

            // 重新来过一次
            findNodeBtn.setDisable(false);
        }else {
            searchBox.getSelectionModel().select(0);
        }
    }
    // 右侧: 清除详情表单
    @FXML
    protected void clearShowAction(ActionEvent event){
        showNodeName.clear();
        showNodeTxt.clear();
        showNodeType.clear();
        showNodePath.clear();
    }
    // -------------------------------------------------------------------->展开/折叠
    // 折叠全部
    @FXML
    protected void collapseAction(ActionEvent event){
        TreeItem<JsonNodeItem> activeNode = (TreeItem<JsonNodeItem>) treeViewer.getFocusModel().getFocusedItem();
        if(null!=activeNode && !activeNode.isLeaf()){
            //System.out.println("[JTC][2]collapse active node:");
            this.collapseNode(activeNode);
        }else {
            //System.out.println("[JTC][2]collapse root node:");
            collapseNode(treeViewer.getRoot());
        }
    }
    // 展开全部
    @FXML
    protected void expandAction(ActionEvent event){
        TreeItem<JsonNodeItem> activeNode = (TreeItem<JsonNodeItem>) treeViewer.getFocusModel().getFocusedItem();
        if(null!=activeNode && !activeNode.isLeaf()){
            //System.out.println("[JTC][3]expand active node:");
            this.expandNode(activeNode);
        } else {
            //System.out.println("[JTC][3]expand root node:");
            this.expandNode(treeViewer.getRoot());
        }
    }
    // 展开某个节点
    private void expandNode(TreeItem<JsonNodeItem> node){
        // System.out.println("[JTC][3.1]expand action node, children size:"+node.getChildren().size());
        node.setExpanded(true);
        for(TreeItem<JsonNodeItem> curNode: node.getChildren()){
            curNode.setExpanded(true);
            if(curNode.getChildren().size()>0){
                expandNode(curNode);
            }
        }
    }
    // 折叠某个节点
    private void collapseNode(TreeItem<JsonNodeItem> node){
        // System.out.println("[JTC][2.1]collapse action node:");
        node.setExpanded(false);
        for(TreeItem<JsonNodeItem> curNode: node.getChildren()){
            curNode.setExpanded(false);
            if(curNode.getChildren().size()>0){
                collapseNode(curNode);
            }
        }
    }
    // -------------------------------------------------------------------->搜索节点
}
